var gulp = require('gulp'),
    gulpBrowserify = require('gulp-browserify'),
    browserify = require('browserify'),
    concat = require('gulp-concat'),
    jshint = require('gulp-jshint'),
    rename = require('gulp-rename'),
    gulpif = require('gulp-if'),
    html = require('html-browserify'),
    uglify = require('gulp-uglify'),
    minify = require('gulp-minify-css'),
    notify = require('gulp-notify'),
    less = require('gulp-less'),
    fs = require('fs'),
    path = require('path'),
    glob = require('glob'),
    argv = require('yargs').argv,
    watch = require('gulp-watch'),
    parents = require('parents'),
    watchify = require('watchify'),
    stripDebug = require('gulp-strip-debug'),
    plumber = require('gulp-plumber'),
    mustache = require('mustache'),
    browserSync = require('browser-sync').create(),
    reload = browserSync.reload,
    config = require('./config.json');

// 替换路径
var replaceDirReg = /www-server+[^]+static+/;

// 默认时间戳build时就设置了 后面不会修改
var timestamp;
var temporaryTimestamp;

var readTimestamp = function(isInit) {

  if (isInit) {
    timestamp = Date.parse(new Date());
    updateVersion(timestamp);
  } else {
    fs.readFile('./version.txt', function(err, res) {
      var text;

      if (!!res.toString()) {
        timestamp = res.toString();
      } else {
        timestamp = Date.parse(new Date());
        updateVersion(timestamp);
      };
    });
  };
}

var renderHtml = function(moduleName, type) {
  var modulePath = path.join(__dirname, config.gulp.modulePath);
  var viewPath = path.join(__dirname, config.gulp.viewPath);
  var moduleScriptArr = [];
  var venderScriptArr = [];
  var moduleStyleArr = [];
  var venderStyleArr = [];

  // 临时保留
  temporaryTimestamp = Date.parse(new Date());

  glob(modulePath, function (er, files) {
    files.map(function(file, index) {
      var reg = /\.[^]+/;
      var fileName = path.basename(file);
      fileName = fileName.replace(reg, '');

      // 排除生成工具模块
      if (config.gulp.ignoreModule.indexOf(fileName) === -1) {

        if (moduleName === fileName) {

          if (type === 'js') {
            createScriptTag(fileName, moduleScriptArr, null, temporaryTimestamp);
            createStyleTag(fileName, moduleStyleArr);
          } else {
            createScriptTag(fileName, moduleScriptArr);
            createStyleTag(fileName, moduleStyleArr, null, temporaryTimestamp);
          };
        } else {
          createScriptTag(fileName, moduleScriptArr);
          createStyleTag(fileName, moduleStyleArr);
        };
      };
    });
    createScriptTag('vender', venderScriptArr, true);
    createStyleTag('vender', venderStyleArr, true);
    glob(viewPath, function(er, files) {
      var venderScriptTag = venderScriptArr[0];
      var venderStyleTag = venderStyleArr[0];
      files.map(function(file, index) {
        var moduleScript = moduleScriptArr[index];
        var moduleStyle = moduleStyleArr[index];
        var _text = [venderScriptTag, moduleScript, venderStyleTag, moduleStyle].join('');
        var text = `<script>
  window.cdnDomainPath = 'http://localhost:8888';
  var loadJs = function(src, fun){
    var script = null;
    script = document.createElement("script");
    script.type = "text/javascript";
    script.src = src;
    if(typeof fun === "function"){
        script.onreadystatechange = function() {
            var r = script.readyState;
            console.log(src + ": " + r);
            if (r === 'loaded' || r === 'complete') {
                script.onreadystatechange = null;
                fun();
            }
        };
    }

    document.write(script.outerHTML);
  };

  ${_text}
</script>
        `;
        fsWrite(file, text);
      });
      // buildHtml(config.gulp.viewPath, config.gulp.destHtmlPath);
    });
  });
}

var updateVersion = function(dateStr) {
  var path = './version.txt';

  fs.writeFile(path, dateStr, function(err){

    if (err)
      console.log("fail " + err);
    else {
      console.log("create version success");
    };
  });
};

var fsWrite = function(path, text) {
  fs.writeFileSync(path, text, function (err) {

    if (err) {
      console.log('err');
      throw err;
    } else {
      console.log('写入完成');
    };
  });
};

var createScriptTag = function(scriptName, scriptArr, isVender, temporaryTimestamp) {
  var scriptPath = [];
  var _scriptName = 'scriptName_' + scriptName;
  scriptPath.push(config.gulp.destJsTagPath);

  if (isVender) {
    scriptPath.push(scriptName);
  } else {
    scriptPath.push(scriptName);
    scriptPath.push('/js/index');
  };

  if (argv.min) {
    scriptPath.push('.min');
  };
  scriptPath.push('.js');
  scriptPath.push('?r=' + (temporaryTimestamp || timestamp));
  var scriptTpl =
  `
  loadJs(window.cdnDomainPath + '${scriptPath.join('')}', function(){
    console.log("From jQuery");
  });
  `;


    // var ${_scriptName} = document.createElement('script');
    // ${_scriptName}.src = window.cdnDomainPath + '${scriptPath.join('')}';
    // document.body.appendChild(${_scriptName});

  scriptArr.push(scriptTpl);
  // scriptTag.push('" </script>');
  // scriptArr.push(scriptTag.join(''));

  // scriptArr.push(mustache.render(scriptTagTpl, data));
  // var scriptname = isVender ? scriptName :(scriptName + '/js/index');
  // var isMin = argv.min ? '.min' : '';
  // var timestamp = temporaryTimestamp || timestamp;
};

var createStyleTag = function(styleName, styleArr, isVender, temporaryTimestamp) {
  // var styleTag = [];
  // var cdnPath = argv.min ? config.gulp.cdnDomainPath.prd : config.gulp.cdnDomainPath.src;
  // styleTag.push('<link rel="stylesheet" type="text/css" href="')
  // styleTag.push(cdnPath);
  // styleTag.push(config.gulp.destCssTagPath);
  //
  // if (isVender) {
  //   styleTag.push(styleName);
  // } else {
  //   styleTag.push(styleName);
  //   styleTag.push('/css/index');
  // };
  //
  // if (argv.min) {
  //   styleTag.push('.min');
  // };
  // styleTag.push('.css');
  // styleTag.push('?r=' + (temporaryTimestamp || timestamp));
  // styleTag.push('" />');
  // styleArr.push(styleTag.join(''));

  var stylePath = [];
  var _styleName = 'style_' + styleName;
  stylePath.push(config.gulp.destCssTagPath);

  if (isVender) {
    stylePath.push(styleName);
  } else {
    stylePath.push(styleName);
    stylePath.push('/css/index');
  };

  if (argv.min) {
    stylePath.push('.min');
  };
  stylePath.push('.css');
  stylePath.push('?r=' + (temporaryTimestamp || timestamp));
  var styleTpl =
  `
  var ${_styleName} = document.createElement('link');
  ${_styleName}.href = window.cdnDomainPath + '${stylePath.join('')}';
  ${_styleName}.type = 'text/css';
  ${_styleName}.rel = 'stylesheet';
  document.head.appendChild(${_styleName});
  `;
  styleArr.push(styleTpl);
};

var buildJs = function(path, destPath, file, isVender, callback) {

  if (!!isVender) {
    gulp.src(path)
      .pipe(concat('vender.js'))
      .pipe(gulpif(argv.min, uglify()))
      .pipe(gulpif(argv.min, rename({
        suffix: '.min'
      })))
      .pipe(gulp.dest('./dest/js/'));
  } else {
    gulp.src(path, {
      base: 'static'
    })
    .pipe(gulpBrowserify({
      insertGlobals : true,
      debug : !gulp.env.production,
      transform: html
    }))
    .pipe(gulpif(argv.min, uglify()))
    .pipe(gulpif(argv.min, stripDebug()))
    .pipe(gulpif(argv.min, rename({
      suffix: '.min'
    })))
    .pipe(gulp.dest('./dest/js/'))
    .pipe(gulpif(!!file, notify('update file ==> ' + file)));
  };
  callback && callback();
};

var buildCss = function(path, destPath, file, isVender, callback) {

  if (!!isVender) {
    gulp.src(path, {
      base: 'static'
    })
    .pipe(concat('vender.css'))
    .pipe(gulpif(argv.min, minify()))
    .pipe(gulpif(argv.min, rename({
      suffix: '.min'
    })))
    .pipe(gulp.dest(config.gulp.destCssPath));
  } else {
    gulp.src(path, {
      base: 'static'
    })
    .pipe(less())
    .pipe(gulpif(argv.min, minify()))
    .pipe(gulpif(argv.min, rename({
      suffix: '.min'
    })))
    .pipe(gulp.dest(config.gulp.destCssPath))
    .pipe(gulpif(!!file, notify('update file ==> ' + file)));
  };
  callback && callback();
};

var buildHtml = function(path, destPath) {
  gulp.src(path)
    .pipe(gulp.dest(destPath))
};

gulp.task('default', function() {
  console.log('default task');
});

// 实时热编译
gulp.task('watch', function() {

  var indexWatcher = gulp.watch(config.gulp.path.js.self.index);
  var otherWatcher = gulp.watch(config.gulp.path.js.self.other);
  var venderWatcher = gulp.watch(config.gulp.path.js.self.vender, ['js-vender-module']);
  var superOtherWatcher = gulp.watch(config.gulp.path.js.super.other, ['js-index-module']);
  var cssIndexWatcher = gulp.watch(config.gulp.path.css.self.index);
  var cssVenderWatcher = gulp.watch(config.gulp.path.css.self.vender, ['css-vender-module']);
  var superCssWatcher = gulp.watch(config.gulp.path.css.super.index, ['css-index-module']);

  // 监听 index 文件的改变
  // todo => index
  // indexWatcher.on('change', function(event) {
  //   var reg = /\.[^]+/;
  //   var file = event.path;
  //   var dirs = parents(file);
  //   var moduleName = path.basename(dirs[2]);
  //   var type = path.basename(file).split('.')[1];
  //   var changeFile = path.join(dirs[1], 'index.js');
  //   buildJs(changeFile, config.gulp.destJsPath, file, false, function() {
  //     renderHtml(moduleName, type);
  //   });
  // });

  indexWatcher.on('change', reload);

  // 监听 other 文件的改变
  // todo => index
  otherWatcher.on('change', function(event) {
    var reg = /\.[^]+/;
    var file = event.path;
    var dirs = parents(file);
    var changeFile = path.join(dirs[1], 'index.js');
    var moduleName = path.basename(dirs[2]);
    var type = path.basename(file).split('.')[1];
    buildJs(changeFile, config.gulp.destJsPath, file, false, function() {
      renderHtml(moduleName, type);
    });
  });

  // 监听 vender 文件的改变
  venderWatcher.on('change', function(event) {
    console.log('File ' + event.path + 'to vender success');
  });

  // 监听 www-server js文件变化
  // super app change => self index dest
  superOtherWatcher.on('change', function(event) {
    console.log('superOtherWatcher task success');
  });

  // 监听模块内 css 的变化
  cssIndexWatcher.on('change', function(event) {
    var file = event.path;
    var reg = /\.[^]+/;
    var dirs = parents(file);
    var moduleName = path.basename(dirs[2]);
    var type = path.basename(file).split('.')[1];
    buildCss(file, config.gulp.destJsPath, file, false, function() {
      renderHtml(moduleName, type);
    });
  });

  // 监听模块内 vender-css 的变化
  cssVenderWatcher.on('change', function(event) {
    console.log('File ' + event.path + 'to vender success');
  });

  // 监听 www-server less文件变化
  // super app change => self index dest
  superCssWatcher.on('change', function(event) {
    console.log('superOtherWatcher task success');
  });
  readTimestamp();
});

// 整体编译
gulp.task('build', ['init', 'js-all-module', 'css-all-module', 'html-module'], function() {
  console.log('build task success');
});

gulp.task('init', function() {
  readTimestamp(true);
});

// 打包所有js模块
gulp.task('js-all-module', ['js-index-module', 'js-vender-module'], function() {});

// 打包所有业务模块内的index.js文件
gulp.task('js-index-module', function() {
  buildJs(config.gulp.path.js.self.index, config.gulp.destJsPath);
});

// gulp.task('js-other-module', function() {
//   buildJs(config.gulp.path.js.self.other, config.gulp.destJsPath);
// });

gulp.task('js-vender-module', function() {
  buildJs(config.gulp.path.js.self.vender, config.gulp.destJsPath, null, true);
});

gulp.task('css-all-module', ['css-index-module', 'css-vender-module'], function() {
  console.log('task css-all-module success');
});

gulp.task('css-index-module', function() {
  buildCss(config.gulp.path.css.self.index, config.gulp.destCssPath);
});

gulp.task('css-vender-module', function() {
  buildCss(config.gulp.path.css.self.vender, config.gulp.destCssPath, null, true);
});

// html内生成script标签
gulp.task('html-module', function() {
  renderHtml();
});

// 静态服务器
gulp.task('browser-sync', function() {
  browserSync.init({      // 启动Browsersync服务
   proxy: "localhost:8888"
 });
});
